home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q1082.dms / q1082.adf / src.lzh / Fig / panel.c < prev    next >
C/C++ Source or Header  |  1991-07-18  |  21KB  |  821 lines

  1. /* 
  2.  *    FIG : Facility for Interactive Generation of figures
  3.  *
  4.  *    Copyright (c) 1985 by Supoj Sutanthavibul (supoj@sally.UTEXAS.EDU)
  5.  *    January 1985.
  6.  *    1st revision : Aug 1985.
  7.  *
  8.  *    %W%    %G%
  9. */
  10. #include "fig.h"
  11. #include "resources.h"
  12. #include "const.h"
  13. #include "func.h"
  14. #include "object.h"
  15. #include "paintop.h"
  16.  
  17. extern            null_proc();
  18.  
  19. /**************     local variables and routines   **************/
  20.  
  21. #ifdef    X11
  22. typedef struct
  23. {
  24.     TOOL    widget;
  25.     Pixmap    normal, reverse;
  26. } button_info;
  27. #endif    X11
  28.  
  29. #include "panel.h"
  30.  
  31. static            panel_selected();
  32. static            panel_sighandler();
  33. static            init_switch();
  34. static F_switch        *switch_selected();
  35. static            panel_selected();
  36. static            switch_handler();
  37. static            switch_action();
  38. static            mode_on();
  39. static            mode_off();
  40. static            set_command();
  41. static            set_geometry();
  42. static            set_grid();
  43. static            set_style();
  44.  
  45. #define            on_action(z)    (z->on_func)(z)
  46. #define            off_action(z)    (z->off_func)(z)
  47.  
  48. F_switch        switches[] = { 
  49.     { 0, 0, 0, 0, &cirrad_ic, F_CIRCLE_BY_RAD, set_command, null_proc, S_ON, },
  50.     { 0, 0, 1, 0, &cirdia_ic, F_CIRCLE_BY_DIA, set_command, null_proc, S_ON, },
  51.     { 0, 0, 0, 1, &ellrad_ic, F_ELLIPSE_BY_RAD, set_command, null_proc, S_ON, },
  52.     { 0, 0, 1, 1, &elldia_ic, F_ELLIPSE_BY_DIA, set_command, null_proc, S_ON, },
  53.     { 0, 0, 0, 2, &c_spl_ic, F_CLOSED_SPLINE, set_command, null_proc, S_ON, },
  54.     { 0, 0, 1, 2, &spl_ic, F_SPLINE, set_command, null_proc, S_ON, },
  55.     { 0, 0, 0, 3, &c_intspl_ic, F_CLOSED_INTSPLINE, set_command, null_proc, S_ON, },
  56.     { 0, 0, 1, 3, &intspl_ic, F_INTSPLINE, set_command, null_proc, S_ON, },
  57.     { 0, 0, 0, 4, &box_ic, F_BOX, set_command, null_proc, S_ON, },
  58.     { 0, 0, 1, 4, &polygon_ic, F_POLYGON, set_command, null_proc, S_ON, },
  59.     { 0, 0, 0, 5, &line_ic, F_POLYLINE, set_command, null_proc, S_ON, },
  60.     { 0, 0, 1, 5, &text_ic, F_TEXT, set_command, null_proc, S_ON, },
  61.     { 0, 0, 0, 6, &arc_ic, F_CIRCULAR_ARC, set_command, null_proc, S_ON, },
  62.     { 0, 0, 1, 6, &turn_ic, F_TURN, set_command, null_proc, S_ON, },
  63.     { 0, 0, 0, 8, &glue_ic, F_GLUE, set_command, null_proc, S_ON, },
  64.     { 0, 0, 1, 8, &break_ic, F_BREAK, set_command, null_proc, S_ON, },
  65.     { 0, 0, 0, 9, &scale_ic, F_SCALE, set_command, null_proc, S_ON, },
  66.     { 0, 0, 1, 9, &autoarrow_ic, F_AUTOARROW, set_command, null_proc, S_ON, },
  67.     { 0, 0, 0, 10, &addpt_ic, F_ADD_POINT, set_command, null_proc, S_ON, },
  68.     { 0, 0, 1, 10, &deletept_ic, F_DELETE_POINT, set_command, null_proc, S_ON, },
  69.     { 0, 0, 0, 11, &move_ic, F_MOVE, set_command, null_proc, S_ON, },
  70.     { 0, 0, 1, 11, &movept_ic, F_MOVE_POINT, set_command, null_proc, S_ON, },
  71.     { 0, 0, 0, 12, ©_ic, F_COPY, set_command, null_proc, S_ON, },
  72.     { 0, 0, 1, 12, &remove_ic, F_REMOVE, set_command, null_proc, S_ON, },
  73.     { 0, 0, 0, 13, &flip_x_ic, F_FLIP_XAXIS, set_command, null_proc, S_ON, },
  74.     { 0, 0, 1, 13, &flip_y_ic, F_FLIP_YAXIS, set_command, null_proc, S_ON, },
  75.     { 0, 0, 0, 14, &rot90_ic, F_ROTATE90, set_command, null_proc, S_ON, },
  76.     { 0, 0, 1, 14, &rot270_ic, F_ROTATE270, set_command, null_proc, S_ON, },
  77.     { 0, 1, 0, 16, &grid1_ic, F_GRID1, set_grid, set_grid, S_TOG, },
  78.     { 0, 1, 1, 16, &grid2_ic, F_GRID2, set_grid, set_grid, S_TOG, },
  79.     { 1, 2, 0, 17, &unconstraint_ic, F_UNCONSTRAINT, set_geometry, null_proc, S_ON, },
  80.     { 0, 2, 1, 17, &mounthattan_ic, F_MOUNTHATTAN, set_geometry, null_proc, S_ON, },
  81.     { 0, 2, 0, 18, &manhattan_ic, F_MANHATTAN, set_geometry, null_proc, S_ON, },
  82.     { 0, 2, 1, 18, &mountain_ic, F_MOUNTAIN, set_geometry, null_proc, S_ON, },
  83.     { 0, 2, 0, 19, &latexline_ic, F_LATEX_LINE, set_geometry, null_proc, S_ON, },
  84.     { 0, 2, 1, 19, &latexarrow_ic, F_LATEX_ARROW, set_geometry, null_proc, S_ON, },
  85.     { 0, -1, 0, 20, &backarrow_ic, F_AUTOB_ARROW, mode_on, mode_off, S_TOG, },
  86.     { 0, -1, 1, 20, &forarrow_ic, F_AUTOF_ARROW, mode_on, mode_off, S_TOG, },
  87.     { 1, 3, 0, 21, &solidline_ic, F_SET_SOLID_LINE, set_style, null_proc, S_ON, },
  88.     { 0, 3, 1, 21, &dashline_ic, F_SET_DASH_LINE, set_style, null_proc, S_ON, },
  89.     { 0, 3, 1, 22, &dottedline_ic, F_SET_DOTTED_LINE, set_style, null_proc, S_ON, },
  90.     { 1, -1, 1, 23, &magnet_ic, F_MAGNET, mode_on, mode_off, S_TOG, },
  91.     };
  92.  
  93. #define            NUM_GROUP    4
  94. #define            NUM_SWITCH    (sizeof(switches) / sizeof(F_switch))
  95. static F_switch        *group[NUM_GROUP];
  96.  
  97. /*
  98.  *    Panel subwindow section
  99.  */
  100.  
  101. #ifndef    X11
  102. #ifdef AMIGA
  103. int N_SWITCHES=    (sizeof(switches)/sizeof(switches[0]));
  104. #else
  105. init_panel(tool)
  106. TOOL        tool;
  107. {
  108.     INPUTMASK        mask;
  109.  
  110.     panel_sw = tool_createsubwindow(tool, "", -1, -1);
  111.     if (panel_sw == (TOOLSW) 0) return(0);
  112.     panel_swfd = panel_sw->ts_windowfd;
  113.     panel_pixwin = pw_open(panel_swfd);
  114.  
  115.     panel_sw->ts_io.tio_selected = panel_selected;
  116.     panel_sw->ts_io.tio_handlesigwinch = panel_sighandler;
  117.     panel_sw->ts_destroy = null_proc;
  118.  
  119.     input_imnull(&mask);
  120.     win_setinputcodebit(&mask, MS_LEFT);
  121.     win_setinputcodebit(&mask, MS_MIDDLE);
  122.     win_setinputcodebit(&mask, MS_RIGHT);
  123.     win_setinputmask(panel_swfd, &mask, NULL, WIN_NULLLINK);
  124.     win_setcursor(panel_swfd, &arrow_cursor);
  125.     (void)fcntl(panel_swfd, F_SETFL, fcntl(panel_swfd, F_GETFL, 0) | O_NDELAY);
  126.     init_switch();
  127.     return(1);
  128.     }
  129. #endif AMIGA
  130. #else
  131. static Arg    panel_args[] =
  132. {
  133.     { XtNx, (XtArgVal)0 },
  134.     { XtNy, (XtArgVal)0 },
  135.     { XtNwidth, (XtArgVal)0 },
  136.     { XtNheight, (XtArgVal)0 },
  137.     { XtNhSpace, (XtArgVal)SWITCH_ICON_SPACING },
  138.     { XtNvSpace, (XtArgVal)SWITCH_ICON_SPACING },
  139.     /* Fix the size of the panel window by chaining both top & bottom
  140.        to the top, and both left & right to the right */
  141.     { XtNtop, (XtArgVal)XtChainTop},
  142.     { XtNbottom, (XtArgVal)XtChainTop},
  143.     { XtNleft, (XtArgVal)XtChainLeft },
  144.     { XtNright, (XtArgVal)XtChainLeft },
  145.     { XtNresizable, (XtArgVal) FALSE },
  146. };
  147.  
  148. extern void button_select();
  149.  
  150. static XtCallbackRec    button_callbacks[] =
  151. {
  152.     { button_select, NULL },
  153.     { NULL, NULL },
  154. };
  155.  
  156. static Arg    button_args[] =
  157. {
  158.     { XtNx, (XtArgVal)0 },
  159.     { XtNy, (XtArgVal)0 },
  160.     { XtNlabel, (XtArgVal)"        " },
  161.     { XtNwidth, (XtArgVal)0 },
  162.     { XtNheight, (XtArgVal)0 },
  163.     { XtNbackgroundPixmap, (XtArgVal)NULL },
  164.     { XtNcallback, (XtArgVal)button_callbacks },
  165.     { XtNresizable, (XtArgVal) FALSE },
  166. };
  167.  
  168. extern int    PANEL_LEFT, PANEL_TOP, PANEL_HEIGHT, PANEL_WID;
  169. extern int    CANVAS_HEIGHT, ICON_COLUMN;
  170.  
  171. #define    N_SWITCHES    (sizeof(switches)/sizeof(switches[0]))
  172. int init_panel(tool)
  173.     TOOL        tool;
  174. {
  175.     register int        i;
  176.     register F_switch    *sw;
  177.  
  178.     panel_args[2].value = PANEL_WID =
  179.         (SWITCH_ICON_WIDTH + 2 + SWITCH_ICON_SPACING) * ICON_COLUMN
  180. /* 2 for borders on switches */
  181.         + SWITCH_ICON_SPACING;
  182.     panel_args[3].value = PANEL_HEIGHT = CANVAS_HEIGHT + RULER_WIDTH + MSG_HEIGHT;
  183.     panel_sw = XtCreateWidget("panel", boxWidgetClass, tool, panel_args,
  184.         XtNumber(panel_args));
  185.     for (i = 0; i < N_SWITCHES; ++i)
  186.     {
  187.         sw = &switches[i];
  188.         button_args[0].value = sw->x * sw->icon->width;
  189.         button_args[1].value = sw->y * sw->icon->height;
  190.         button_args[3].value = sw->icon->width;
  191.         button_args[4].value = sw->icon->height;
  192.         button_callbacks[0].closure = (caddr_t)sw;
  193.         sw->but.widget = XtCreateManagedWidget(
  194.             "button", commandWidgetClass,
  195.             panel_sw, button_args, XtNumber(button_args));
  196.     }
  197.     return (1);
  198. }
  199.  
  200. setup_panel()
  201. {
  202.     register int        i;
  203.     register F_switch    *sw;
  204.     register Display    *d = tool_d;
  205.     register Screen        *s = tool_s;
  206.     register Pixmap        p;
  207.     register GC        cgc;
  208.     XGCValues        gcv;
  209.     Arg            tmp_arg[3];
  210.     long            bg, fg;
  211.     
  212.     cgc = XCreateGC(d, XtWindow(panel_sw), 0, &gcv);
  213.     XtSetArg(tmp_arg[0], XtNbackground, &bg);
  214.     XtSetArg(tmp_arg[1], XtNforeground, &fg);
  215.     XtGetValues(switches[0].but.widget, tmp_arg, 2);
  216.     XSetForeground(d, cgc, fg);
  217.     XSetBackground(d, cgc, bg);
  218.     
  219.     for (i = 0; i < N_SWITCHES; ++i)
  220.     {
  221.         sw = &switches[i];
  222. /*
  223. **    You'd think XCreateBitmapFromBitmapData would work but
  224. **    unfortunately it wants LSB first data.
  225. */
  226.         p = XCreatePixmap(d, XtWindow(sw->but.widget),
  227.                   sw->icon->width, sw->icon->height,
  228.                   DefaultDepthOfScreen(s));
  229.         XPutImage(d, p, cgc, sw->icon, 0, 0, 0, 0, sw->icon->width,
  230.             sw->icon->height);
  231.         sw->but.normal = button_args[5].value = (XtArgVal)p;
  232.         XtSetValues(sw->but.widget, &button_args[5], 1);
  233.     }
  234. /*
  235. **    Create reversed bitmaps for displaying activated state
  236. */
  237.     XSetForeground(d, cgc, bg);
  238.     XSetBackground(d, cgc, fg);
  239.     for (i = 0; i < N_SWITCHES; ++i)
  240.     {
  241.         sw = &switches[i];
  242.         p = XCreatePixmap(d, XtWindow(sw->but.widget),
  243.                   sw->icon->width, sw->icon->height,
  244.                   DefaultDepthOfScreen(s));
  245.         XPutImage(d, p, cgc, sw->icon, 0, 0, 0, 0, sw->icon->width,
  246.             sw->icon->height);
  247.         sw->but.reverse = (XtArgVal)p;
  248.     }
  249.     XFreeGC(d, cgc);
  250.     init_switch();
  251.     panel_pixwin = panel_swfd = XtWindow(panel_sw);
  252.     XDefineCursor(d, panel_swfd, (Cursor)arrow_cursor.bitmap);
  253. }
  254.  
  255. static void button_select(widget, s)
  256.     TOOL        widget;
  257.     F_switch    *s;
  258. {
  259.     switch_action(s);
  260. }
  261. #endif    X11
  262.  
  263. #ifndef    X11
  264. #ifdef AMIGA
  265. #else
  266. static
  267. panel_selected(nullsw, ibits, obits, ebits, timer)
  268. caddr_t        *nullsw;
  269. int        *ibits, *obits, *ebits;
  270. struct timeval    *timer;
  271. {
  272.     extern int        action_on;
  273.     extern int        receiving_msg;
  274.     INPUTEVENT        ie;
  275.     int            x, y;
  276.  
  277.     x = -1;
  278.     while (input_readevent(panel_swfd, &ie) != -1) {
  279.         if (ie.ie_code == MS_LEFT) {
  280.         x = ie.ie_locx;
  281.         y = ie.ie_locy;
  282.         }
  283.         }
  284.     *ibits = *obits = *ebits = 0;
  285.     if (action_on) return;
  286.     if (receiving_msg) return;  /* ignore mouse input when msg is being
  287.                     accepted    */
  288.     if (x != -1) switch_handler(x, y);
  289.     }
  290.  
  291. static
  292. panel_sighandler()
  293. {
  294.     pw_damaged(panel_pixwin);
  295.     pw_writebackground(panel_pixwin, 0, 0, 2048, 2048, PAINT);
  296.     redisplay_panel();
  297.     pw_donedamaged(panel_pixwin);
  298.     }
  299.  
  300. redisplay_panel()
  301. {
  302.     F_switch    *s, *t;
  303.  
  304.     t = &switches[NUM_SWITCH-1];
  305.     for (s = switches; s <= t; s++) {
  306.         if (s->on == 1)
  307.         turn_on(s);
  308.         else 
  309.         turn_off(s);
  310.         }
  311.     }
  312.  
  313. static F_switch *
  314. switch_selected(x, y)
  315. int    x, y;
  316. {
  317.     F_switch    *sw;
  318.     int        i;
  319.  
  320.     for (sw = switches, i = 0; i < NUM_SWITCH; sw++, i++) {
  321.         if (sw->x > x || sw->x + SWITCH_ICON_WIDTH < x) continue;
  322.         if (sw->y <= y && y <= sw->y + SWITCH_ICON_HEIGHT) return(sw);
  323.         }
  324.     return(NULL); /* no item is selected */
  325.     }
  326. #endif AMIGA
  327. #endif    X11
  328.  
  329. init_switch()
  330. {
  331.     extern int    manhattan_mode;
  332.     extern int    mountain_mode;
  333.     extern int    autoforwardarrow_mode;
  334.     extern int    autobackwardarrow_mode;
  335.     extern int    latexline_mode;
  336.     extern int    latexarrow_mode;
  337.     extern int    magnet_mode;
  338.     extern int    cur_line_style;
  339.     extern float    cur_styleval;
  340.     extern float    cur_dashlength;
  341.     extern float    cur_dotgap;
  342.     int        i;
  343.     F_switch    *sw;
  344.  
  345.     for (sw = switches, i = 0; i < NUM_SWITCH; sw++, i++) {
  346.         sw->x *= SWITCH_ICON_WIDTH;
  347.         sw->y *= SWITCH_ICON_HEIGHT;
  348.         }
  349.     for (i = 0; i < NUM_GROUP; ) group[i++] = NULL;
  350.  
  351.     for (sw = switches, i = 0; i < NUM_SWITCH; sw++, i++) {
  352.         if (sw->on) {
  353.         /* Only the following switch can be preset */
  354.         switch (sw->value) {
  355.             case F_UNCONSTRAINT :
  356.             manhattan_mode = 0;
  357.             mountain_mode = 0;
  358.             latexline_mode = 0;
  359.             latexarrow_mode = 0;
  360.             group[sw->group] = sw;
  361.             break;
  362.             case F_MOUNTHATTAN :
  363.             manhattan_mode = 1;
  364.             mountain_mode = 1;
  365.             group[sw->group] = sw;
  366.             break;
  367.             case F_MANHATTAN :
  368.             manhattan_mode = 1;
  369.             group[sw->group] = sw;
  370.             break;
  371.             case F_MOUNTAIN :
  372.             mountain_mode = 1;
  373.             group[sw->group] = sw;
  374.             break;
  375.             case F_LATEX_LINE :
  376.             latexline_mode = 1;
  377.             group[sw->group] = sw;
  378.             break;
  379.             case F_LATEX_ARROW :
  380.             latexarrow_mode = 1;
  381.             group[sw->group] = sw;
  382.             break;
  383.             case F_AUTOF_ARROW :
  384.             autoforwardarrow_mode = 1;
  385.             break;
  386.             case F_AUTOB_ARROW :
  387.             autobackwardarrow_mode = 1;
  388.             break;
  389.             case F_SET_SOLID_LINE :
  390.             cur_line_style = SOLID_LINE;
  391.             cur_styleval = 0.0;
  392.             break;
  393.             case F_SET_DASH_LINE :
  394.             cur_line_style = DASH_LINE;
  395.             cur_styleval = cur_dashlength;
  396.             break;
  397.             case F_SET_DOTTED_LINE :
  398.             cur_line_style = DOTTED_LINE;
  399.             cur_styleval = cur_dotgap;
  400.             break;
  401.             case F_MAGNET :
  402.             magnet_mode = 1;
  403.             break;
  404.             default :
  405.             continue;
  406.             }
  407.         turn_on(sw);
  408.         if (sw->group != -1) group[sw->group] = sw;
  409.         }
  410.         }
  411.     }
  412.  
  413. #ifndef    X11
  414. #ifndef AMIGA
  415. static
  416. switch_handler(x, y)
  417. int    x, y;
  418. {
  419.     F_switch *s;
  420.  
  421.     if (NULL == (s = switch_selected(x, y))) return;
  422.     switch_action(s);
  423.     }
  424. #endif AMIGA
  425. #endif    X11
  426.  
  427. static
  428. set_command(sw)
  429. F_switch    *sw;
  430. {
  431.     extern int    cur_command;
  432.     extern int    rotate_angle;
  433.     extern int    flip_axis;
  434.  
  435.     switch (sw->value) {
  436.         case F_CIRCLE_BY_RAD :
  437.         circlebyradius_drawing_selected();
  438.         erase_pointmarker();
  439.         erase_compoundbox();
  440.         put_msg("CIRCLE drawing: specify RADIUS");
  441.         break;
  442.         case F_CIRCLE_BY_DIA :
  443.         circlebydiameter_drawing_selected();
  444.         erase_pointmarker();
  445.         erase_compoundbox();
  446.         put_msg("CIRCLE drawing: specify DIAMETER");
  447.         break;
  448.         case F_ELLIPSE_BY_RAD :
  449.         ellipsebyradius_drawing_selected();
  450.         erase_pointmarker();
  451.         erase_compoundbox();
  452.         put_msg("ELLIPSE drawing: specify RADIUSES");
  453.         break;
  454.         case F_ELLIPSE_BY_DIA :
  455.         ellipsebydiameter_drawing_selected();
  456.         erase_pointmarker();
  457.         erase_compoundbox();
  458.         put_msg("ELLIPSE drawing: specify DIAMETERS");
  459.         break;
  460.         case F_BOX :
  461.         box_drawing_selected();
  462.         erase_pointmarker();
  463.         erase_compoundbox();
  464.         put_msg("Rectangular BOX drawing");
  465.         break;
  466.         case F_POLYGON :
  467.         line_drawing_selected();
  468.         erase_pointmarker();
  469.         erase_compoundbox();
  470.         put_msg("POLYGON drawing");
  471.         break;
  472.         case F_POLYLINE :
  473.         line_drawing_selected();
  474.         erase_pointmarker();
  475.         erase_compoundbox();
  476.         put_msg("POLYLINE drawing");
  477.         break;
  478.         case F_TEXT :
  479.         text_drawing_selected();
  480.         erase_pointmarker();
  481.         erase_compoundbox();
  482.         put_msg("TEXT input (from keyboard)");
  483.         break;
  484.         case F_CIRCULAR_ARC :
  485.         arc_drawing_selected();
  486.         erase_pointmarker();
  487.         erase_compoundbox();
  488.         put_msg("ARC drawing: specify three points on the arc");
  489.         break;
  490.         case F_SPLINE :
  491.         draw_spline_selected();
  492.         erase_pointmarker();
  493.         erase_compoundbox();
  494.         put_msg("SPLINE drawing: specify control points");
  495.         break;
  496.         case F_CLOSED_SPLINE :
  497.         draw_spline_selected();
  498.         erase_pointmarker();
  499.         erase_compoundbox();
  500.         put_msg("CLOSED SPLINE drawing: specify control points");
  501.         break;
  502.         case F_INTSPLINE :
  503.         draw_intspline_selected();
  504.         erase_pointmarker();
  505.         erase_compoundbox();
  506.         put_msg("INTERPOLATED SPLINE drawing");
  507.         break;
  508.         case F_CLOSED_INTSPLINE :
  509.         draw_intspline_selected();
  510.         erase_pointmarker();
  511.         erase_compoundbox();
  512.         put_msg("CLOSED INTERPOLATED SPLINE drawing");
  513.         break;
  514.         case F_GLUE :
  515.         compound_selected();
  516.         erase_pointmarker();
  517.         show_compoundbox();
  518.         put_msg("GLUE objects into COMPOUND object with bounding box");
  519.         break;
  520.         case F_BREAK :
  521.         break_selected();
  522.         erase_pointmarker();
  523.         show_compoundbox();
  524.         put_msg("BREAK COMPOUND object");
  525.         break;
  526.         case F_SCALE :
  527.         scale_compound_selected();
  528.         erase_pointmarker();
  529.         show_compoundbox();
  530.         put_msg("SCALE COMPOUND object");
  531.         break;
  532.         case F_ADD_POINT :
  533.         point_adding_selected();
  534.         show_pointmarker();
  535.         erase_compoundbox();
  536.         put_msg("ADD POINTs (to POLYLINE, POLYGON, CLOSED-SPLINE and SPLINE)");
  537.         break;
  538.         case F_DELETE_POINT :
  539.         delete_point_selected();
  540.         show_pointmarker();
  541.         erase_compoundbox();
  542.         put_msg("DELETE POINTs (from POLYLINE, POLYGON, CLOSED-SPLINE and SPLINE)");
  543.         break;
  544.         case F_MOVE :
  545.         move_selected();
  546.         show_pointmarker();
  547.         show_compoundbox();
  548.         put_msg("MOVE objects");
  549.         break;
  550.         case F_MOVE_POINT :
  551.         move_point_selected();
  552.         show_pointmarker();
  553.         erase_compoundbox();
  554.         put_msg("MOVE POINTs (of POLYLINE, POLYGON, CLOSED-SPLINE, SPLINE and BOX)");
  555.         break;
  556.         case F_REMOVE :
  557.         remove_selected();
  558.         show_pointmarker();
  559.         show_compoundbox();
  560.         put_msg("REMOVE objects");
  561.         break;
  562.         case F_COPY :
  563.         copy_selected();
  564.         show_pointmarker();
  565.         show_compoundbox();
  566.         put_msg("COPY objects");
  567.         break;
  568.         case F_ROTATE270 :
  569.         rotate_selected();
  570.         show_pointmarker();
  571.         show_compoundbox();
  572.         rotate_angle = 270;
  573.         put_msg("ROTATE objects (middle button) or COPY & ROTATE (left button) -90 degree");
  574.         break;
  575.         case F_ROTATE90 :
  576.         rotate_selected();
  577.         show_pointmarker();
  578.         show_compoundbox();
  579.         rotate_angle = 90;
  580.         put_msg("ROTATE objects (middle button) or COPY & ROTATE (left button) 90 degree");
  581.         break;
  582.         case F_FLIP_XAXIS :
  583.         flip_selected();
  584.         show_pointmarker();
  585.         show_compoundbox();
  586.         flip_axis = 1;
  587.         put_msg("FLIP objects (middle button) or COPY & FLIP (left button) up or down");
  588.         break;
  589.         case F_FLIP_YAXIS :
  590.         flip_selected();
  591.         show_pointmarker();
  592.         show_compoundbox();
  593.         flip_axis = 2;
  594.         put_msg("FLIP objects (middle button) or COPY & FLIP (left button) left or right");
  595.         break;
  596.         case F_TURN :
  597.         turn_selected();
  598.         show_pointmarker();
  599.         erase_compoundbox();
  600.         put_msg("Turn POLYGON (POLYLINE) into CLOSED-SPLINE (SPLINE) or vice versa");
  601.         break;
  602.         case F_AUTOARROW :
  603.         arrow_head_selected();
  604.         show_pointmarker();
  605.         erase_compoundbox();
  606.         put_msg("ADD arrow head (left button); DELETE arrow head (middle button)");
  607.         break;
  608.         }
  609.     cur_command = sw->value;
  610.     }
  611.  
  612. static
  613. set_geometry(sw)
  614. F_switch    *sw;
  615. {
  616.     extern int    manhattan_mode;
  617.     extern int    mountain_mode;
  618.     extern int    latexline_mode;
  619.     extern int    latexarrow_mode;
  620.  
  621.     switch (sw->value) {
  622.         case F_UNCONSTRAINT :
  623.         manhattan_mode = 0;
  624.         mountain_mode = 0;
  625.         latexline_mode = 0;
  626.         latexarrow_mode = 0;
  627.         put_msg("UNCONSTRAINT geometry (for POLYLINE and SPLINE)");
  628.         break;
  629.         case F_MOUNTHATTAN :
  630.         mountain_mode = 1;
  631.         manhattan_mode = 1;
  632.         latexline_mode = 0;
  633.         latexarrow_mode = 0;
  634.         put_msg("MOUNT-HATTAN geometry (for POLYLINE and SPLINE)");
  635.         break;
  636.         case F_MANHATTAN :
  637.         manhattan_mode = 1;
  638.         mountain_mode = 0;
  639.         latexline_mode = 0;
  640.         latexarrow_mode = 0;
  641.         put_msg("MANHATTAN geometry (for POLYLINE and SPLINE)");
  642.         break;
  643.         case F_MOUNTAIN :
  644.         mountain_mode = 1;
  645.         manhattan_mode = 0;
  646.         latexline_mode = 0;
  647.         latexarrow_mode = 0;
  648.         put_msg("MOUNTAIN geometry (for POLYLINE and SPLINE)");
  649.         break;
  650.         case F_LATEX_LINE :
  651.         latexline_mode = 1;
  652.         manhattan_mode = 0;
  653.         mountain_mode = 0;
  654.         latexarrow_mode = 0;
  655.         put_msg("LATEX LINE geometry: allow only LaTeX line slopes");
  656.         break;
  657.         case F_LATEX_ARROW :
  658.         latexarrow_mode = 1;
  659.         manhattan_mode = 0;
  660.         mountain_mode = 0;
  661.         latexline_mode = 0;
  662.         put_msg("LATEX ARROW geometry: allow only LaTeX arrow slopes");
  663.         break;
  664.         }
  665.     }
  666.  
  667. static
  668. set_grid(sw)
  669. F_switch    *sw;
  670. {
  671.     setup_grid(sw->value);
  672.     }
  673.  
  674. static
  675. mode_on(sw)
  676. F_switch    *sw;
  677. {
  678.     extern int    autoforwardarrow_mode;
  679.     extern int    autobackwardarrow_mode;
  680.     extern int    magnet_mode;
  681.  
  682.     switch (sw->value) {
  683.         case F_AUTOF_ARROW :
  684.         autoforwardarrow_mode = 1;
  685.         put_msg("AUTO FORWARD ARROW (for ARC, POLYLINE and SPLINE)");
  686.         break;
  687.         case F_AUTOB_ARROW :
  688.         autobackwardarrow_mode = 1;
  689.         put_msg("AUTO BACKWARD ARROW (for ARC, POLYLINE and SPLINE)");
  690.         break;
  691.         case F_MAGNET :
  692.         magnet_mode = 1;
  693.         put_msg("MAGNET: round entered points to the nearest 1/16\" increment");
  694.         break;
  695.         }
  696.     }
  697.  
  698. static
  699. mode_off(sw)
  700. F_switch    *sw;
  701. {
  702.     extern int    autoforwardarrow_mode;
  703.     extern int    autobackwardarrow_mode;
  704.     extern int    magnet_mode;
  705.  
  706.     switch (sw->value) {
  707.         case F_AUTOF_ARROW :
  708.         autoforwardarrow_mode = 0;
  709.         break;
  710.         case F_AUTOB_ARROW :
  711.         autobackwardarrow_mode = 0;
  712.         break;
  713.         case F_MAGNET :
  714.         magnet_mode = 0;
  715.         break;
  716.         }
  717.     }
  718.  
  719. static
  720. set_style(sw)
  721. F_switch    *sw;
  722. {
  723.     extern int    cur_line_style;
  724.     extern float    cur_styleval;
  725.     extern float    cur_dashlength;
  726.     extern float    cur_dotgap;
  727.  
  728.     switch (sw->value) {
  729.         case F_SET_SOLID_LINE :
  730.         cur_line_style = SOLID_LINE;
  731.         cur_styleval = 0.0;
  732.         put_msg("SOLID LINE STYLE (for BOX, POLYGON and POLYLINE)");
  733.         break;
  734.         case F_SET_DASH_LINE :
  735.         cur_line_style = DASH_LINE;
  736.         cur_styleval = cur_dashlength;
  737.         put_msg("DASH LINE STYLE (for BOX, POLYGON and POLYLINE)");
  738.         break;
  739.         case F_SET_DOTTED_LINE :
  740.         cur_line_style = DOTTED_LINE;
  741.         cur_styleval = cur_dotgap;
  742.         put_msg("DOTTED LINE STYLE (for BOX, POLYGON and POLYLINE)");
  743.         break;
  744.         }
  745.     }
  746.  
  747. #ifndef    X11
  748. static
  749. turn_on(s)
  750. F_switch    *s;
  751. {
  752.     s->on = 1;
  753.     pw_write(panel_pixwin, s->x, s->y,
  754.         SWITCH_ICON_WIDTH, SWITCH_ICON_HEIGHT, ERASE, s->icon, 0, 0);
  755.     }
  756.  
  757. static
  758. turn_off(s)
  759. F_switch    *s;
  760. {
  761.     s->on = 0;
  762.     pw_write(panel_pixwin, s->x, s->y,
  763.         SWITCH_ICON_WIDTH, SWITCH_ICON_HEIGHT, PAINT,
  764.         s->icon, 0, 0);
  765.     }
  766. #else
  767. static turn_on(s)
  768.     F_switch    *s;
  769. {
  770.     s->on = 1;
  771.     button_args[5].value = (XtArgVal)s->but.reverse;
  772.     XtSetValues(s->but.widget, &button_args[5], 1);
  773. }
  774.  
  775. static turn_off(s)
  776.     F_switch    *s;
  777. {
  778.     s->on = 0;
  779.     button_args[5].value = (XtArgVal)s->but.normal;
  780.     XtSetValues(s->but.widget, &button_args[5], 1);
  781. }
  782. #endif    X11
  783.  
  784. switch_action(sw)
  785. F_switch    *sw;
  786. {
  787.     F_switch    *old;
  788.  
  789.     if (sw == NULL) return;
  790.  
  791.     if (sw->group == -1) {
  792.         if (sw->on) {
  793.         turn_off(sw);
  794.         off_action(sw);
  795.         }
  796.         else {
  797.         turn_on(sw);
  798.         on_action(sw);
  799.         }
  800.         return;
  801.         }
  802.  
  803.     old = group[sw->group];
  804.     if (old == sw) {
  805.         if (old->type != S_ON) {
  806.         turn_off(old);
  807.         off_action(old);
  808.         group[old->group] = NULL;
  809.         }
  810.         return;
  811.         }
  812.     else if (old) {
  813.         turn_off(old);
  814.         off_action(old);
  815.         }
  816.  
  817.     turn_on(sw);
  818.     on_action(sw);
  819.     group[sw->group] = sw;
  820.     }
  821.